package com.zhdl.network.strategy.common_server.impl;

import cn.hutool.core.util.HexUtil;
import com.google.common.eventbus.Subscribe;
import com.project.command.faq.queues.data.ControlInstructionPerformData;
import com.project.command.instruction.service.InstructionSendService;
import com.project.common.constant.Dic;
import com.zhdl.common.ytools.callback.CommonCallback;
import com.zhdl.common.ytools.eventbus.center.EventBusCenter;
import com.zhdl.modules.demo.hardware_connect.ReceiverMessageInterface;
import com.zhdl.network.common_server.CommonTcpServerAfter;
import com.zhdl.network.common_server.resp.CommonServerEvent;
import com.zhdl.network.strategy.common_server.CommonServerSendService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.util.LinkedHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

@Slf4j
@Service("TcpIPServerSendReceiver")
public class CommonServerSendServiceImpl implements CommonServerSendService {

    private static final String hexString = "0123456789ABCDEF";
    /**
     * 服务端的在线列表
     */
    public final LinkedHashMap<String, CopyOnWriteArrayList<String>> serverClientList = new LinkedHashMap<>();
    /**
     * 服务端的回调列表
     */
    private final LinkedHashMap<String, CopyOnWriteArrayList<CommonCallback<String>>> callbackLinkedHashMap = new LinkedHashMap<>();
    /**
     * 硬件数据接收 管理器
     */
    private ReceiverMessageInterface receiverMessageInterface;
    /**
     * 调取服务端指令发送的方法
     */
    @Resource
    private InstructionSendService instructionSendService;

    public void setReceiverMessageInterface(ReceiverMessageInterface receiverMessageInterface) {
        this.receiverMessageInterface = receiverMessageInterface;
    }

    public static String encodeCN(String data) {
        byte[] bytes;
        try {
            bytes = data.getBytes("gbk");
            StringBuilder sb = new StringBuilder(bytes.length * 2);
            for (byte aByte : bytes) {
                sb.append(hexString.charAt((aByte & 0xf0) >> 4));
                sb.append(hexString.charAt((aByte & 0x0f)));
            }
            return sb.toString();
        } catch (UnsupportedEncodingException e) {
            log.error(e.getMessage(), e);
//            e.printStackTrace();
        }
        return "";
    }

    @Subscribe
    public void dataReception(CommonServerEvent event) {
        if (receiverMessageInterface!=null){
            receiverMessageInterface.receiverMsg(event.getServerIpPort(),event.getReceiveData());
        }
        String portKey = event.getServerIpPort();
        CopyOnWriteArrayList<CommonCallback<String>> commonCallbacks = callbackLinkedHashMap.get(portKey);
 //       log.info("TcpServerEventBusData{}", event);
//        log.info("callbackLinkedHashMap{}", callbackLinkedHashMap);
        if (!commonCallbacks.isEmpty()) {
            for (CommonCallback<String> stringCommonCallback : commonCallbacks) {
                if (stringCommonCallback != null) {
                    stringCommonCallback.statusCallback(HexUtil.encodeHexStr(event.getReceiveData()));
                }
            }
        }
    }

    /**
     * 添加启动的服务到 内存RAM
     *
     * @param ipPort 服务端的IP
     */
    public void addServer(String ipPort) {
        serverClientList.put(ipPort, new CopyOnWriteArrayList<>());
        callbackLinkedHashMap.put(ipPort, new CopyOnWriteArrayList<>());
        EventBusCenter.getEventBus().register(this);
    }

    /**
     * 在服务端下 从指定服务 发送到 服务下的客户端 指定指令
     *
     * @param server 需要发出的服务端IP
     * @param client 需要接收的客户端IP
     * @param cmd    指令
     */
    public synchronized void sendToClientCmd(String server, String client, String cmd) {
        CopyOnWriteArrayList<String> clients = serverClientList.get(server);
        if (clients == null || clients.isEmpty()) {
            log.info("当前Server服务:{},不存在", server);
            log.info("serverClientList{}", serverClientList);
            log.info("callbackLinkedHashMap{}", callbackLinkedHashMap);
            return;
        }
        if (!clients.contains(client)) {
            log.info("当前Server服务:{},找不到IP为:{}的Client客户端连接...", server, client);
            return;
        }
        ControlInstructionPerformData data = new ControlInstructionPerformData();
        data.setInstruction(HexUtil.decodeHex(cmd));
        data.setPortKey(server);
        data.setDstAdd(client);
        data.setProtocols(Dic.HAND_MODBUS_RTU_ANALYSIS);
        data.setAfterInstructionName(CommonTcpServerAfter.COMMON_TCP_SERVER_AFTER_SERVICE);
        data.setDataBit(10);
        data.setChain(cmd);
        instructionSendService.sendToClient(data);
    }

    /**
     * 在服务端下 添加连接的客户端
     *
     * @param server 服务端地址
     * @param client 客户端地址
     */
    public void addClientToServer(String server, String client) {
        //找到服务端下的List集合
        CopyOnWriteArrayList<String> clients = serverClientList.get(server);

        if (clients == null) {
            log.debug("当前服务:{}-可能尚未创立,请创建后重试", server);
            return;
        }

        clients.add(client);
        log.debug("当前服务:{}-正常存在,有一个新的客户端已连接:{},当前客户端列表为:{}", server, client, clients);
    }

    /**
     * 在服务端下 清除掉线的客户端
     *
     * @param server 服务端地址
     * @param client 客户端地址
     */
    public void deleteClient(String server, String client) {
        CopyOnWriteArrayList<String> clients = serverClientList.get(server);
        if (clients == null || clients.isEmpty()) {
            log.debug("当前服务:{}-尚未找到,请确定服务端Ip后重试", server);
            return;
        }
        clients.remove(client);
        log.debug("当前服务:{}-正常存在,有一个新的客户端已掉线:{},当前客户端列表为:{}", server, client, clients);
    }

    public void setDataCallBack(String server, CommonCallback<String> callback) {
        CopyOnWriteArrayList<CommonCallback<String>> commonCallbacks = callbackLinkedHashMap.get(server);
        if (commonCallbacks == null) {
            log.info("当前服务{}不存在!!!!", server);
        } else {
            commonCallbacks.add(callback);
        }
    }
}
